package com.teamtwoseven.todo;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.TextView;

/**
 * Allows an expandable list of items to be displayed on-screen.
 * 
 * @author teamtwoseven
 */
public class ListAdapter extends BaseExpandableListAdapter {
	
	private Item[] items; // the Items to show in the list
	private String[] itemNames; // Expandable list entries for the item names
	private String[] itemInfo; // Hide-able list entries for the item info
	private Context context;
	private Button[] bEdit, bDelete, bLocation;
	private CheckBox[] cbCompleted; // each item has a checkbox for done/to-do
	private OnClickListener listener;

	public ListAdapter(Context context, Item[] items,
		OnClickListener listener) {
		
		this.context = context;
		this.listener = listener;
		
		if (items != null && items.length > 0) {
			// Copy the given array of items and populate all list entries
			this.items = items;
			itemNames = new String[items.length];
			itemInfo = new String[items.length];
			
			for (int i = 0; i < items.length; i++) {
				String frequency = items[i].getFrequency();
				String date = new SimpleDateFormat("MM/dd/yyyy' 'h:mma").format(
						new Date(items[i].getDeadline()));
				
				if (frequency.equals("Daily")) {
					frequency = "Every Day, at " + date.substring(11);
				}
				else if (frequency.equals("Weekly")) {
					Calendar calendar = Calendar.getInstance();
					int year = 2012, month, day;
					String weekDay;
					
					month = (date.charAt(0) - 48) * 10 + (date.charAt(1) - 48);
					day = (date.charAt(3) - 48) * 10 + (date.charAt(4) - 48);
					
					for (int j = 6, multiple = 1000; j < date.length(); j++, multiple/=10) {
						year += (date.charAt(j) - 48) * multiple;
					}
					
					switch (calendar.get(Calendar.DAY_OF_WEEK)) {
					case 1:
						weekDay = "Sunday";
						break;
					case 2:
						weekDay = "Monday";
						break;
					case 3:
						weekDay = "Tuesday";
						break;
					case 4:
						weekDay = "Wednesday";
						break;
					case 5:
						weekDay = "Thursday";
						break;
					case 6:
						weekDay = "Friday";
						break;
					case 7:
						weekDay = "Saturday";
						break;
					default:
						weekDay = "so often";
						break;
					}
					
				    calendar.set(Calendar.YEAR, year);
				    calendar.set(Calendar.DAY_OF_YEAR, month*day);
				    
				    frequency = "Every " + weekDay +
				    	" at " + date.substring(11);
				}
				else if (frequency.equals("Monthly")) {
					frequency = "The " + date.substring(3,5) +
							" of each month, at " + date.substring(11);
				}
				else {
					frequency = date;
				}
				
				itemNames[i] = items[i].getName();
				itemInfo[i] = items[i].getDescription() + "\n" + "Deadline: "
					 + frequency + "\nCategory: " + items[i].getCategory() +
					 "\nLocation: " + items[i].getLocation(); 
			}

			// Allow one edit button, delete button, and checkbox per item
			bEdit = new Button[items.length];
			bDelete = new Button[items.length];
			bLocation = new Button[items.length];
			cbCompleted = new CheckBox[items.length];
		}
		else { // just to be safe...
			itemNames = new String[0];
			itemInfo = new String[0];
		}
	}

	/**
	 * Returns the info for the item with the name at index groupPosition.
	 * 
	 * @param groupPosition
	 * 			index of an item name in the list; 0 is the top index
	 * @param childPosition
	 * 			ignored since each item name has only one child - the item info
	 * @return the item info at index groupPosition, or a message indicating
	 * 			there is no item info here (which would mean an error occurred)
	 */
	public String getChild(int groupPosition, int childPosition) {
		return (itemInfo == null)? "No Info For Item " + 
			itemNames[groupPosition]: itemInfo[groupPosition];
	}

	/**
	 * Returns the ID of the item info at index groupPosition. The ID for item
	 * info is the index groupPosition + the number of item names in the list.
	 * 
	 * @param groupPosition
	 * 			index of an item name in the list; 0 is the top index
	 * @param childPosition
	 * 			ignored since each item name has only one child - the item info
	 * @return the ID of the item info
	 */
	public long getChildId(int groupPosition, int childPosition) {
		return groupPosition + items.length;
	}

	/**
	 * Sets the graphical aspects of the item info at index groupPosition.
	 *
	 * @param groupPosition
	 *			the index of an item name in the list; 0 is the top index
	 * @param childPosition
	 * 			ignored since each item name has only one child - the item info
	 * @param isLastChild
	 *			items have just one list entry for info, so this is always true
	 * @param convertView
	 * 			a View to use with this item info
	 * @param parent
	 * 			the ViewGroup this item info is a part of
	 * @return the View for this item info
	 */
	public View getChildView(int groupPosition, int childPosition,
		boolean isLastChild, View convertView, ViewGroup parent) {

		// Set the graphical layout for this hide-able list entry
		if (convertView == null) {
			LayoutInflater inflater = (LayoutInflater)
					context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
			convertView = inflater.inflate(R.layout.child_row, null);
		}

		// Display the item info under this item name
		TextView childname = (TextView)
				convertView.findViewById(R.id.childRow_tvChildName);
		if (itemInfo != null) {
			childname.setText(itemInfo[groupPosition]);
		}

		// Alternate colors between hide-able list entries
		if(groupPosition % 2 == 0){
			convertView.setBackgroundColor(0x30ffffff);
		}
		else{
			convertView.setBackgroundColor(0x00ffffff);
		}

		// Create and add a listener to the check/edit/delete buttons
		bEdit[groupPosition] =
			(Button) convertView.findViewById(R.id.childRow_bEditItem);
		bEdit[groupPosition].setOnClickListener(listener);
		
		bDelete[groupPosition] =
			(Button) convertView.findViewById(R.id.childRow_bDeleteItem);
		bDelete[groupPosition].setOnClickListener(listener);

		bLocation[groupPosition] =
			(Button) convertView.findViewById(R.id.childRow_bLocation);
		bLocation[groupPosition].setOnClickListener(listener);

		cbCompleted[groupPosition] = (CheckBox)
				convertView.findViewById(R.id.childRow_cbCompleted);
		cbCompleted[groupPosition].setOnClickListener(listener);
		
		// Check checkboxes for done items; leave to-dos unchecked
		cbCompleted[groupPosition].setChecked(items[groupPosition].isDone());
		
		return convertView;
	}

	/**
	 * Returns 1, the number of hide-able list entries per item name.
	 * 
	 * @return 1, the number of entries for item info below each item name
	 */
	public int getChildrenCount(int groupPosition) {
		return 1;
	}

	/**
	 * Returns the item name at index groupPosition as it appears in the list.
	 * 
	 * @param groupPosition
	 * 			the index of an item name in the list; 0 is the top index
	 * @param childPosition
	 * 			ignored since each item name has only one child - the item info
	 * @return the item name at index groupPosition, or a message indicating
	 * 			there is no item name here (which would mean an error occurred)
	 */
	public String getGroup(int groupPosition) {
		return (itemNames == null)? "Item Name Not Found":
			itemNames[groupPosition];
	}

	/**
	 * Returns the number of item names in the list.
	 * 
	 * @return the number of item names in the list
	 */
	public int getGroupCount() {
		return (itemNames == null)? 0: itemNames.length;
	}

	/**
	 * Returns groupPosition.
	 * 
	 * @param groupPosition
	 * 			the index of an item name in the list; 0 is the top index
	 * @return the ID of the item name at the given index
	 */
	public long getGroupId(int groupPosition) {
		return groupPosition;
	}

	/**
	 * Sets the graphical aspects of the item name at index groupPosition
	 *
	 * @param groupPosition
	 *			the index of an item name in the list; 0 is the top index
	 * @param isExpanded
	 *			if true, the item info is showing
	 * @param convertView
	 * 			a View to use with this item name
	 * @param parent
	 * 			the ViewGroup this item name is a part of
	 * @return the View for this item name
	 */
	public View getGroupView(int groupPosition, boolean isExpanded,
		View convertView, ViewGroup parent) {

		// Set the graphical layout for this expandable list entry
		if (convertView == null) {
			LayoutInflater inflater =  (LayoutInflater)
					context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
			convertView = inflater.inflate(R.layout.group_row, null);
		}

		// Display the item name for this list entry
		TextView groupname = (TextView)
				convertView.findViewById(R.id.groupRow_tvGroupName);
		if (itemNames != null) {
			groupname.setText(itemNames[groupPosition]);
		}

		// Alternate colors between expandable list entries
		if(groupPosition % 2 == 0){
			convertView.setBackgroundColor(0x30ffffff);
		}
		else{
			convertView.setBackgroundColor(0x00ffffff);
		}

		return convertView;
	}

	/**
	 * Returns false.
	 * 
	 * @return false
	 */
	public boolean hasStableIds() {
		return false;
	}

	/**
	 * Returns false.
	 * 
	 * @param groupPosition
	 * 			the index of an item name in the list; 0 is the top index
	 * @param childPosition
	 * 			ignored since each item name has only one child - the item info
	 * @return false
	 */
	public boolean isChildSelectable(int groupPosition, int childPosition) {
		return false;
	}
	
	public Button[] getEditButtons() {
		return bEdit;
	}
	
	public Button[] getDeleteButtons() {
		return bDelete;
	}
	
	public Button[] getLocationButtons() {
		return bLocation;
	}
	
	public CheckBox[] getCheckBoxes() {
		return cbCompleted;
	}
	
	public Item[] getItems() {
		return items;
	}
	
	/**
	 * If the items[i] is done, it becomes not done. If it is not done, it
	 * becomes done. The checkbox for the item is then set to reflect the
	 * change.
	 * 
	 * @param i
	 * 			index of the item in the Item array for this ListAdapter object
	 */
	public void toggleDone(int i) {
		cbCompleted[i].setChecked(items[i].toggleDone());
	}
}